/// @NOTE: this file is included from Quaternion2D.hpp, IN cvMath:: namespace.


template<typename T> Quat2<T>::Quat2() : z(0), w(1) {}	/* zero quanternion */
template<typename T> Quat2<T>::Quat2(const Quat2<T> &copy) : z(copy.z), w(copy.w) {}

template<typename T> Quat2<T>::Quat2(const Vec2<T> &zw)
{
	z = zw.x;
	w = zw.y;
}

template<typename T> Quat2<T>& Quat2<T>::operator= (const Quat2<T> &copy)
{
	z = copy.z;
	w = copy.w;
	return *this;
}

template<typename T> Quat2<T>::Quat2(T angle, T roll)
{
	const T half = (angle / 2.0) * DEGREES_TO_RAD;
	z = roll * sin(half);
	w = cos(half);
};


template<typename T> Quat2<T>& operator+= (Quat2<T> &left, const Quat2<T> &right)
{
    left.z += right.z;
    left.w += right.w;
    return left;
};

template<typename T> Quat2<T>& operator-= (Quat2<T> &left, const Quat2<T> &right)
{
    left.z -= right.z;
    left.w -= right.w;
    return left;
};

template<typename T> Quat2<T>& operator*= (Quat2<T> &left, const Quat2<T> &right)
{
	const T t0 = left.z;
    left.z = t0*right.z - left.w*right.w;
    left.w = t0*right.w + left.w*right.z;
    return left;
};

template<typename T> Quat2<T>& zero(Quat2<T>& q)
{
	return *(new (&q) Quat2<T>(0.0 , 1.0)); /* trick compiler to reconstruct this object, without assigment */
}

template<typename T> Quat2<T>& normalize(Quat2<T> &q)
{
	const T invdist = 1.0 / sqrt(q.z * q.z + q.w + q.w);
	q.z *= invdist;
	q.w *= invdist;
	return q;
};

